Skip to content

Conversation

logaretm
Copy link
Collaborator

@logaretm logaretm commented Oct 3, 2025

What

This PR adds automatic instrumentation for Nuxt's storage layer (powered by unstorage), enabling performance monitoring for cache and key-value storage operations in Nuxt/Nitro applications.

Storage operations will now automatically create performance spans with detailed attributes for observability in Sentry.

What's New

  • Automatic Storage Instrumentation: Instruments all storage drivers configured in nuxt.config.ts via nitro.storage
  • Comprehensive Coverage: Tracks all storage operations including:
    • getItem, setItem, hasItem, removeItem
    • Raw variants: getItemRaw, setItemRaw
    • Batch operations: getItems, setItems
    • Utility methods: getKeys, clear
    • Aliases: get, set, has, del, remove

Implementation Details

Span Attributes:

  • sentry.op: cache.{operation} (e.g., cache.get_item, cache.set_item)
  • sentry.origin: auto.cache.nuxt
  • cache.key: Full key including mount prefix
  • cache.hit: true for successful get/has operations
  • db.operation.name: Original method name
  • db.collection.name: Storage mount point
  • db.system.name: Driver name (e.g., memory, fs, redis)

Files Changed:

  • packages/nuxt/src/runtime/plugins/storage.server.ts - Runtime instrumentation plugin
  • packages/nuxt/src/vite/storageConfig.ts - Build-time configuration
  • packages/nuxt/src/module.ts - Module integration
  • E2E tests for Nuxt 3 & 4

Copy link

linear bot commented Oct 3, 2025

@logaretm logaretm force-pushed the awad/js-1016-nuxtnitro-instrument-kv-storage-instrumenting-unstorage branch from 07cb542 to 24a5470 Compare October 3, 2025 15:40
@logaretm logaretm linked an issue Oct 3, 2025 that may be closed by this pull request
@logaretm logaretm self-assigned this Oct 4, 2025
@logaretm logaretm marked this pull request as ready for review October 6, 2025 12:28
@logaretm logaretm force-pushed the awad/js-1016-nuxtnitro-instrument-kv-storage-instrumenting-unstorage branch from a6dc41f to fe203a5 Compare October 6, 2025 12:29
cursor[bot]

This comment was marked as outdated.

cursor[bot]

This comment was marked as outdated.

@logaretm logaretm requested review from andreiborza and s1gr1d October 6, 2025 12:55
@logaretm logaretm force-pushed the awad/js-1016-nuxtnitro-instrument-kv-storage-instrumenting-unstorage branch from 911b7fe to abe38de Compare October 8, 2025 10:34
cursor[bot]

This comment was marked as outdated.

@logaretm logaretm force-pushed the awad/js-1016-nuxtnitro-instrument-kv-storage-instrumenting-unstorage branch from 64e5814 to 42ef2c7 Compare October 9, 2025 09:02
Copy link
Contributor

github-actions bot commented Oct 9, 2025

size-limit report 📦

Path Size % Change Change
@sentry/browser 24.64 kB - -
@sentry/browser - with treeshaking flags 23.14 kB - -
@sentry/browser (incl. Tracing) 40.85 kB - -
@sentry/browser (incl. Tracing, Replay) 79.21 kB - -
@sentry/browser (incl. Tracing, Replay) - with treeshaking flags 68.92 kB - -
@sentry/browser (incl. Tracing, Replay with Canvas) 83.91 kB - -
@sentry/browser (incl. Tracing, Replay, Feedback) 96.08 kB - -
@sentry/browser (incl. Feedback) 41.33 kB - -
@sentry/browser (incl. sendFeedback) 29.3 kB - -
@sentry/browser (incl. FeedbackAsync) 34.26 kB - -
@sentry/react 26.35 kB - -
@sentry/react (incl. Tracing) 42.84 kB - -
@sentry/vue 29.13 kB - -
@sentry/vue (incl. Tracing) 42.64 kB - -
@sentry/svelte 24.66 kB - -
CDN Bundle 26.94 kB - -
CDN Bundle (incl. Tracing) 41.53 kB - -
CDN Bundle (incl. Tracing, Replay) 77.8 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) 83.28 kB - -
CDN Bundle - uncompressed 78.95 kB - -
CDN Bundle (incl. Tracing) - uncompressed 123.07 kB - -
CDN Bundle (incl. Tracing, Replay) - uncompressed 238.23 kB - -
CDN Bundle (incl. Tracing, Replay, Feedback) - uncompressed 251 kB - -
@sentry/nextjs (client) 44.9 kB - -
@sentry/sveltekit (client) 41.27 kB - -
@sentry/node-core 50.78 kB +0.01% +2 B 🔺
@sentry/node 154.4 kB -0.01% -1 B 🔽
@sentry/node - without tracing 92.65 kB - -
@sentry/aws-serverless 106.35 kB - -

View base workflow run

cursor[bot]

This comment was marked as outdated.

Copy link
Contributor

node-overhead report 🧳

Note: This is a synthetic benchmark with a minimal express app and does not necessarily reflect the real-world performance impact in an application.

Scenario Requests/s % of Baseline Prev. Requests/s Change %
GET Baseline 8,877 - 8,903 -0%
GET With Sentry 1,389 16% 1,367 +2%
GET With Sentry (error only) 6,253 70% 6,204 +1%
POST Baseline 1,216 - 1,208 +1%
POST With Sentry 511 42% 526 -3%
POST With Sentry (error only) 1,063 87% 1,069 -1%
MYSQL Baseline 3,353 - 3,350 +0%
MYSQL With Sentry 479 14% 438 +9%
MYSQL With Sentry (error only) 2,722 81% 2,715 +0%

View base workflow run

@logaretm logaretm force-pushed the awad/js-1016-nuxtnitro-instrument-kv-storage-instrumenting-unstorage branch 3 times, most recently from 83bb4e8 to f5cd0ca Compare October 15, 2025 10:31
cursor[bot]

This comment was marked as outdated.

@logaretm logaretm force-pushed the awad/js-1016-nuxtnitro-instrument-kv-storage-instrumenting-unstorage branch from 83e35f8 to d621605 Compare October 15, 2025 20:54
Comment on lines +125 to +127
if (CACHE_HIT_METHODS.has(methodName)) {
span.setAttribute(SEMANTIC_ATTRIBUTE_CACHE_HIT, !isEmptyValue(result));
}
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if we should always treat data retrieval as a cache hit 🤔 This also adds this attribute even though it's not specifically set up as a Nitro cache, right?

Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I figured KVs as a low latency storage are being used primarily as a cache, I don't think we can infer the user intention here.

Given that it can expire via TTL, I thought to treat it as cache.

I don't have a strong opinion, what do you think?

Copy link
Member

@s1gr1d s1gr1d left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In general, all good to go. Just some comments

@logaretm logaretm merged commit 8e3afe2 into develop Oct 16, 2025
38 checks passed
@logaretm logaretm deleted the awad/js-1016-nuxtnitro-instrument-kv-storage-instrumenting-unstorage branch October 16, 2025 21:16
logaretm added a commit that referenced this pull request Oct 17, 2025
Adds [Nitro/Nuxt Cache API](https://nitro.build/guide/cache)
instrumentation by building upon the storage instrumentation in #17858
since both use `unstorage` under the hood.

#### How it works

Nitro injects the cache storage on either `cache:` or the root mount
depending on user configuration, also in production the `cache` storage
is placed on the root mount unless the user configures it explicitly to
redis or something else. We instrument both mount drivers to cover other
cache use cases.

---

I made sure to add e2e tests as well for `cachedEventListner` and
`cachedFunction` calls which are the main ways to use the Cache API.

This PR depends on the storage PR #17858.

---------

Co-authored-by: Sigrid Huemer <32902192+s1gr1d@users.noreply.github.com>
logaretm added a commit that referenced this pull request Oct 17, 2025
This pull request introduces automatic instrumentation for database
queries in Nuxt applications in server side handlers using Sentry.

#### Implementation Details

- Instruments database `.sql`, `.prepare` and `.exec` calls.
- Adds breadcrumbs and spans following cloudflare's D1 implementation.

This relies on the work done in #17858 and #17886
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Nuxt/Nitro] Instrument KV Storage (instrumenting unstorage)

2 participants